We are migrating the bug tracker to github Issues. This is now the preferred way to report NASM bugs.
Self-registration is disabled due to spam issue (mail gorcunov@gmail.com or hpa@zytor.com to create an account)
Here's a test case in which the "Bit value is zero!" message occurs, but no "symbol not defined before use" error happens. I assume it might be that the preprocessor %error is somehow of a higher priority and swallows the other error due to undefined symbol. $ cat test.asm ; This macro is used to generate byte or word access to specific ; bits of a dword variable. ; %1 = token: if "~", bit value will be negated after checking ; %2 = instruction ; %3 = variable, in the form "[address]" without size specification ; %4 = bit value(s) to access ; %5 = bool: disable word access warning, defaults to 0 ; If the value in %4 has bits set in different bytes so that ; a single 8- or 16-bit instruction cannot access all the bits, ; an error is displayed. This insures that the macro only has ; to generate one instruction, as a 32-bit access on 16-bit ; CPUs requires multiple instructions. This workaround code ; needs to be written specifically then, or the flags have to ; be re-ordered to allow the access. %macro _opt 4-5.nolist 0 %push %defstr %$adr %3 %strlen %$len %$adr %substr %$tf %$adr 1 %substr %$tb %$adr %$len %substr %$adr %$adr 2,-2 %deftok %$adr %$adr %ifnidn %$tf,"[" %error Invalid memory access syntax %elifnidn %$tb,"]" %error Invalid memory access syntax %elifn %4 %error Bit value is zero! Check code. %elifn (%4) & ~0FFh %2 byte [%$adr], %1(%4) %elifn (%4) & ~0FF00h %2 byte [%$adr+1], %1((%4)>>8) %elifn (%4) & ~0FF0000h %2 byte [%$adr+2], %1((%4)>>16) %elifn (%4) & ~0FF000000h %2 byte [%$adr+3], %1((%4)>>24) %elifn (%4) & ~0FFFFh %ifn %5 %warning Macro generated word access %endif %2 word [%$adr], %1(%4) %elifn (%4) & ~0FFFF00h %ifn %5 %warning Macro generated word access %endif %2 word [%$adr+1], %1((%4)>>8) %elifn (%4) & ~0FFFF0000h %ifn %5 %warning Macro generated word access %endif %2 word [%$adr+2], %1((%4)>>16) %else %error Unsupported macro usage, requires dword: %ifempty %1 %error %2 dword [%$adr], %4 %else %error %2 dword [%$adr], %1(%4) %endif %endif %pop %endmacro ; User forms for above macro. ; %1 = variable, in the form "[address]" without size specification ; %2 = bit value(s) to access ; %3 = bool: disable word access warning, defaults to 0 ; testopt tests the specified bits (using a "test" instruction) and ; leaves a meaningful result in ZF, as well as NC. ; clropt clears the specified bits (using an "and" instruction with ; the negated value) and leaves NC, but a random ZF. ; setopt sets the specified bits (using an "or" instruction) and ; leaves NC, NZ. ; xoropt toggles the specified bits (using a "xor" instruction) and ; leaves NC, but a random ZF. %idefine testopt _opt ,test, %idefine clropt _opt ~,and, %idefine setopt _opt ,or, %idefine xoropt _opt ,xor, definedequ equ 4 %if definedequ %warning definedequ is true %endif %ifdef ERROR %if undefinedequ %warning undefinedequ is true %endif %endif %ifdef ERROR %if definedequ | undefinedequ %warning definedequ | undefinedequ is true %endif %endif foo: testopt [foo], definedequ | undefinedequ $ nasm test.asm test.asm:84: warning: definedequ is true [-w+user] test.asm:101: error: (_opt:13) Bit value is zero! Check code. $ nasm test.asm -DERROR test.asm:88: error: symbol `undefinedequ' not defined before use test.asm:94: error: symbol `undefinedequ' not defined before use $ nasm -v NASM version 2.14 $
Shorter test case: $ cat test2.asm definedequ equ 4 %macro mac 1.nolist %if 0 == 1 %error Really should not see this. %elifn %1 %error Preprocessor %error directive message. %endif %endmacro mac definedequ | undefinedequ $ nasm test2.asm test2.asm:12: error: (mac:4) Preprocessor %error directive message. $ nasm -v NASM version 2.14 $
Ok, seems like the real problem is that the error message gets promoted because we encounter an error before pass 1. At the very least it should not be emitted in the very first pass (passn == 1), perhaps not in any of the optimization passes either (pass0 == 0). If it happens in the stabilization pass we have a phase error, but perhaps the best is to defer this to pass 2 and let the phase error be signalled as-is. Ideally, we would keep track of preprocessor changes between the stabilization and code-generation passes just like we do symbol changes; this would require recording every preprocessor event ideally in some form that can be resynchronized after an error.